package com.macro.mall.component;

import com.alibaba.fastjson.JSON;
import com.macro.mall.common.config.RedisTool;
import com.macro.mall.common.exception.ApiException;
import com.macro.mall.common.service.RedisService;
import com.macro.mall.common.util.DateUtil;
import com.macro.mall.mapper.PmsProductMapper;
import com.macro.mall.mapper.PmsSkuStockMapper;
import com.macro.mall.model.PmsProduct;
import com.macro.mall.model.PmsSkuStock;
import com.macro.mall.model.PmsSkuStockExample;
import com.quyum.mall.market.config.RedisKey;
import com.quyum.mall.market.entity.MarketSmsRound;
import com.quyum.mall.market.entity.MarketSmsRoundProduct;
import com.quyum.mall.market.example.MarketSmsRoundProductExample;
import com.quyum.mall.market.mapper.MarketSmsRoundMapper;
import com.quyum.mall.market.mapper.MarketSmsRoundProductMapper;
import com.quyum.mall.market.service.bean.RoundService;
import com.quyum.mall.market.service.redis.StartActivityService;
import com.quyum.mall.market.service.stock.HandelStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class StartActivity implements StartActivityService, HandelStockService {
    @Autowired
    private PmsSkuStockMapper pmsSkuStockMapper;
    @Autowired
    private MarketSmsRoundMapper roundMapper;
    @Autowired
    private MarketSmsRoundProductMapper roundProductMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RoundService roundService;
    @Autowired
    private PmsProductMapper productMapper;
    @Override
    public void start(String key) {
        if(key.startsWith(RedisKey.ROUND_KEY_BEFORE)) {
            this.startActivity(key);
        }else if(key.startsWith(RedisKey.ROUND_PRODUCT_KEY)){
            this.stopActivity(key);
        }else if(key.startsWith(RedisKey.ROUND_STARTING_KEY)){
            Long roundId = this.getId(RedisKey.ROUND_STARTING_KEY, key);
            MarketSmsRound smsRound = this.roundMapper.selectByPrimaryKey(roundId);
            smsRound.setStatus(10);
            smsRound.setModifyTime(new Date());
            this.roundMapper.updateByPrimaryKey(smsRound);
        }
    }

    public void startActivity(String key) {
        System.out.println("活动开始----------------1"+ key);
        String lockKey = "doLock:"+RedisKey.ROUND_KEY_BEFORE+ key;
        if(this.redisService.getLock(lockKey,30000)){
            System.out.println("活动开始----------------2"+ key);
            //活动开始
            Long roundId = this.getId(RedisKey.ROUND_KEY_BEFORE, key);
            this.redisService.set(lockKey,lockKey,30);
            MarketSmsRound round = this.roundMapper.selectByPrimaryKey(roundId);
            Integer type = round.getType();
            MarketSmsRoundProductExample example = new MarketSmsRoundProductExample();
            example.createCriteria().andRoundIdEqualTo(roundId);
            List<MarketSmsRoundProduct> roundProducts = this.roundProductMapper.selectByExample(example);
            //处理闪购商品锁库存业务
            if (type.equals(MarketSmsRoundProduct.TYPE.MOMENT_BUYING.VALUE)) {
                if (!CollectionUtils.isEmpty(roundProducts)) {
                    List<Long> skuIds = roundProducts.stream().map(MarketSmsRoundProduct::getSkuId).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(skuIds)) {
                        PmsSkuStockExample stockExample = new PmsSkuStockExample();
                        stockExample.createCriteria().andIdIn(skuIds);
                        List<PmsSkuStock> pmsSkuStocks = this.pmsSkuStockMapper.selectByExample(stockExample);
                        if (!CollectionUtils.isEmpty(pmsSkuStocks)) {
                            pmsSkuStocks.stream().forEach(e -> {
                                e.setActivityLockStock(e.getStock() - e.getLockStock());
                                e.setLockStock(e.getActivityLockStock() + e.getLockStock());
                                this.pmsSkuStockMapper.updateByPrimaryKeySelective(e);
                            });
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(roundProducts)) {
                roundProducts.forEach(e->{
                    this.roundService.addProduct2Redis(DateUtil.getReduce(round.getEndTime()),e);
                });
            }
            //开始活动
            round.setStatus(MarketSmsRound.STATUS.STARTING.value);
            round.setModifyTime(new Date());
            this.roundMapper.updateByPrimaryKey(round);
            round.setProducts(roundProducts);
            System.out.println("roundProducts----------------"+roundProducts.size());
            String s = JSON.toJSONString(round);
            System.out.println("s----------------"+s);
            this.redisService.setMilliSeconds(RedisKey.ROUND_STARTING_KEY+roundId,round, DateUtil.getReduce(round.getEndTime()));
        }else{
            System.out.println("活动开始----------------3"+ key);
        }
    }

    public void stopActivity(String key){
        System.out.println("活动结束----------------1"+ key);
        String lockKey = "doLock:"+RedisKey.ROUND_PRODUCT_KEY+ key;
        if(this.redisService.getLock(lockKey,30000)){
            System.out.println("活动结束----------------2"+ key);
            //活动结束
            Long roundProductId = this.getId(RedisKey.ROUND_PRODUCT_KEY, key);
            this.redisService.set(lockKey,lockKey,30);
            MarketSmsRoundProduct roundProduct = this.roundProductMapper.selectByPrimaryKey(roundProductId);
            if(roundProduct!=null){
                Long skuId = roundProduct.getSkuId();
                Long productId = roundProduct.getProductId();
                String stockProductKey = new StringBuffer(RedisKey.ROUND_SKU_STOCK_KEY).append(productId).append("_").append(skuId).toString();
                MarketSmsRoundProduct redisRoundProduct = (MarketSmsRoundProduct)this.redisService.get(stockProductKey);
                if(redisRoundProduct!=null){
                    roundProduct.setResidueNum(redisRoundProduct.getResidueNum());
                    this.roundProductMapper.updateByPrimaryKeySelective(roundProduct);
                }
                //活动的数量
                this.releaseActivityStock(roundProduct, skuId);
                this.redisService.del(stockProductKey);
            }
        }else{
            System.out.println("活动结束----------------3"+ key);
        }
    }
    @Override
    public void releaseActivityStock(MarketSmsRoundProduct roundProduct, Long skuId) {
        Integer num = roundProduct.getNum();
        PmsSkuStock pmsSkuStock = this.pmsSkuStockMapper.selectByPrimaryKey(skuId);
        pmsSkuStock.setActivityLockStock(pmsSkuStock.getActivityLockStock()-num);
        pmsSkuStock.setLockStock(pmsSkuStock.getLockStock()-num);
        this.pmsSkuStockMapper.updateByPrimaryKeySelective(pmsSkuStock);
    }

    /**
     * 获取key的通用方法
     * @param redisKey
     * @param key
     * @return
     */
    private Long getId(String redisKey,String key){
        String[] split = key.split(redisKey);
        return Long.parseLong(split[1]);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public String lockStock(Long roundId) {
        String msg = "";
        MarketSmsRound round = this.roundMapper.selectByPrimaryKey(roundId);
        Integer type = round.getType();
        MarketSmsRoundProductExample example = new MarketSmsRoundProductExample();
        example.createCriteria().andRoundIdEqualTo(roundId);
        List<MarketSmsRoundProduct> roundProducts = this.roundProductMapper.selectByExample(example);
        //处理锁库存业务
        if(!CollectionUtils.isEmpty(roundProducts)){
            Map<Long, List<MarketSmsRoundProduct>> productsMap = roundProducts.stream().collect(Collectors.groupingBy(MarketSmsRoundProduct::getSkuId));
            List<Long> skuIds = roundProducts.stream().map(MarketSmsRoundProduct::getSkuId).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(skuIds)){
                PmsSkuStockExample stockExample = new PmsSkuStockExample();
                stockExample.createCriteria().andIdIn(skuIds);
                List<PmsSkuStock> pmsSkuStocks = this.pmsSkuStockMapper.selectByExample(stockExample);
                if(!CollectionUtils.isEmpty(pmsSkuStocks)){
                    pmsSkuStocks.forEach(e->{
                        if(!type.equals(MarketSmsRoundProduct.TYPE.MOMENT_BUYING.VALUE)){
                            List<MarketSmsRoundProduct> marketSmsRoundProducts = productsMap.get(e.getId());
                            MarketSmsRoundProduct marketSmsRoundProduct = marketSmsRoundProducts.get(0);
                            if(marketSmsRoundProduct.getNum().compareTo(e.getStock()-e.getLockStock())<=0){
                                e.setActivityLockStock(marketSmsRoundProduct.getNum()+e.getActivityLockStock());
                                e.setLockStock(marketSmsRoundProduct.getNum()+e.getLockStock());
                                this.pmsSkuStockMapper.updateByPrimaryKeySelective(e);
                            }else{
                                PmsProduct pmsProduct = this.productMapper.selectByPrimaryKey(marketSmsRoundProduct.getProductId());
                                throw new ApiException("商品名称："+pmsProduct.getName()+"规格："+e.getSpData()+"库存不足");
                            }
                        }
                    });
                }
            }
        }
        return msg;
    }
    @Override
    public Boolean checkStock(MarketSmsRoundProduct product) {
        Long skuId = product.getSkuId();
        PmsSkuStock pmsSkuStock = this.pmsSkuStockMapper.selectByPrimaryKey(skuId);
        return product.getNum().compareTo(pmsSkuStock.getStock() - pmsSkuStock.getLockStock()) <= 0;
    }
}
